#!/bin/bash

#=============================================================================
# 云打印机基础系统一键启动脚本
# Cloud Printer Base System One-Click Startup Script
#
# 功能说明：
# - 自动检查系统环境和依赖
# - 安装缺失的系统依赖包
# - 配置Python虚拟环境
# - 设置必要的系统权限
# - 启动BLE GATT服务
# - 提供多种启动模式选择
#
# 作者: Cloud Printer Team
# 版本: 1.0.0
# 日期: 2025-08-06
# 许可: MIT License
#=============================================================================

# 脚本配置参数
SCRIPT_NAME="云打印机基础系统启动脚本"
SCRIPT_VERSION="1.0.0"
PROJECT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
VENV_DIR="${PROJECT_DIR}/venv"
CONFIG_DIR="/etc/cloud-printer"
DATA_DIR="/var/lib/cloud-printer"
LOG_DIR="/var/log"
SERVICE_USER="ble-service"

# 颜色输出定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
PURPLE='\033[0;35m'
CYAN='\033[0;36m'
NC='\033[0m' # No Color

# 日志文件路径
LOG_FILE="/tmp/cloud-printer-setup.log"

#=============================================================================
# 工具函数定义
#=============================================================================

# 打印带颜色的信息
print_info() {
    echo -e "${BLUE}[信息]${NC} $1" | tee -a "$LOG_FILE"
}

print_success() {
    echo -e "${GREEN}[成功]${NC} $1" | tee -a "$LOG_FILE"
}

print_warning() {
    echo -e "${YELLOW}[警告]${NC} $1" | tee -a "$LOG_FILE"
}

print_error() {
    echo -e "${RED}[错误]${NC} $1" | tee -a "$LOG_FILE"
}

print_header() {
    echo -e "${PURPLE}[步骤]${NC} $1" | tee -a "$LOG_FILE"
}

# 检查命令是否存在
command_exists() {
    command -v "$1" >/dev/null 2>&1
}

# 检查是否为root用户
check_root() {
    if [[ $EUID -eq 0 ]]; then
        return 0
    else
        return 1
    fi
}

# 请求管理员权限
request_sudo() {
    if ! check_root; then
        print_info "需要管理员权限来安装系统依赖和配置服务"
        sudo -v || {
            print_error "无法获取管理员权限，脚本退出"
            exit 1
        }
    fi
}

# 显示脚本头部信息
show_header() {
    clear
    echo -e "${CYAN}"
    echo "============================================================================="
    echo "  $SCRIPT_NAME"
    echo "  版本: $SCRIPT_VERSION"
    echo "  项目目录: $PROJECT_DIR"
    echo "============================================================================="
    echo -e "${NC}"
    
    # 初始化日志文件
    echo "$(date '+%Y-%m-%d %H:%M:%S') - 开始执行启动脚本" > "$LOG_FILE"
}

#=============================================================================
# 环境检查函数
#=============================================================================

# 检查操作系统
check_os() {
    print_header "1. 检查操作系统环境"
    
    if [[ "$OSTYPE" == "linux-gnu"* ]]; then
        print_success "检测到Linux操作系统"
        
        # 检查发行版
        if command_exists lsb_release; then
            DISTRO=$(lsb_release -si)
            VERSION=$(lsb_release -sr)
            print_info "发行版: $DISTRO $VERSION"
        elif [[ -f /etc/os-release ]]; then
            source /etc/os-release
            print_info "发行版: $NAME $VERSION"
        fi
        
        # 检查架构
        ARCH=$(uname -m)
        print_info "系统架构: $ARCH"
        
    else
        print_error "不支持的操作系统: $OSTYPE"
        print_error "此脚本仅支持Linux系统"
        exit 1
    fi
}

# 检查Python环境
check_python() {
    print_header "2. 检查Python环境"
    
    if command_exists python3; then
        PYTHON_VERSION=$(python3 --version | cut -d' ' -f2)
        print_success "Python3已安装: $PYTHON_VERSION"
        
        # 检查版本是否符合要求（>=3.8）
        PYTHON_MAJOR=$(echo $PYTHON_VERSION | cut -d. -f1)
        PYTHON_MINOR=$(echo $PYTHON_VERSION | cut -d. -f2)
        
        if [[ $PYTHON_MAJOR -ge 3 ]] && [[ $PYTHON_MINOR -ge 8 ]]; then
            print_success "Python版本符合要求（>=3.8）"
        else
            print_warning "Python版本过低，推荐使用3.8+版本"
        fi
    else
        print_error "Python3未安装"
        return 1
    fi
    
    # 检查pip
    if command_exists pip3; then
        print_success "pip3已安装"
    else
        print_warning "pip3未安装，将在依赖安装阶段处理"
    fi
}

# 检查系统服务
check_system_services() {
    print_header "3. 检查系统服务状态"
    
    # 检查蓝牙服务
    if systemctl is-active --quiet bluetooth; then
        print_success "蓝牙服务正在运行"
    else
        print_warning "蓝牙服务未运行，将尝试启动"
    fi
    
    # 检查DBus服务
    if systemctl is-active --quiet dbus; then
        print_success "DBus服务正在运行"
    else
        print_error "DBus服务未运行，这可能导致服务启动失败"
    fi
    
    # 检查NetworkManager
    if systemctl is-active --quiet NetworkManager; then
        print_success "NetworkManager服务正在运行"
    elif systemctl is-active --quiet network-manager; then
        print_success "network-manager服务正在运行"
    else
        print_warning "NetworkManager未运行，WiFi配置功能可能不可用"
    fi
}

# 检查蓝牙硬件
check_bluetooth_hardware() {
    print_header "4. 检查蓝牙硬件"
    
    if command_exists hciconfig; then
        # 检查蓝牙适配器
        if hciconfig >/dev/null 2>&1; then
            ADAPTERS=$(hciconfig | grep "hci" | wc -l)
            if [[ $ADAPTERS -gt 0 ]]; then
                print_success "检测到 $ADAPTERS 个蓝牙适配器"
                
                # 显示适配器详细信息
                hciconfig | grep -E "^hci|UP RUNNING" | while read line; do
                    print_info "  $line"
                done
            else
                print_error "未检测到蓝牙适配器"
                return 1
            fi
        else
            print_warning "无法检查蓝牙适配器状态"
        fi
    else
        print_warning "hciconfig命令不可用，跳过蓝牙硬件检查"
    fi
}

#=============================================================================
# 依赖安装函数
#=============================================================================

# 安装系统依赖
install_system_dependencies() {
    print_header "5. 安装系统依赖包"
    
    # 请求管理员权限
    request_sudo
    
    # 更新包管理器缓存
    print_info "更新包管理器缓存..."
    sudo apt-get update -qq 2>&1 | tee -a "$LOG_FILE" || {
        print_error "无法更新包管理器缓存"
        return 1
    }
    
    # 定义需要安装的包列表
    PACKAGES=(
        "python3-dev"
        "python3-pip" 
        "python3-venv"
        "build-essential"
        "bluetooth"
        "bluez"
        "libbluetooth-dev"
        "libgirepository1.0-dev"
        "gcc"
        "python3-gi"
        "python3-gi-cairo"
        "gir1.2-gtk-3.0"
    )
    
    # 检查并安装缺失的包
    MISSING_PACKAGES=()
    for package in "${PACKAGES[@]}"; do
        if ! dpkg -l | grep -q "^ii  $package "; then
            MISSING_PACKAGES+=("$package")
        fi
    done
    
    if [[ ${#MISSING_PACKAGES[@]} -gt 0 ]]; then
        print_info "需要安装以下包: ${MISSING_PACKAGES[*]}"
        sudo apt-get install -y "${MISSING_PACKAGES[@]}" 2>&1 | tee -a "$LOG_FILE" || {
            print_error "依赖包安装失败"
            return 1
        }
        print_success "系统依赖包安装完成"
    else
        print_success "所有必需的系统依赖包已安装"
    fi
}

# 设置Python虚拟环境
setup_python_environment() {
    print_header "6. 配置Python虚拟环境"
    
    # 检查虚拟环境是否已存在
    if [[ -d "$VENV_DIR" ]]; then
        print_info "虚拟环境已存在: $VENV_DIR"
    else
        print_info "创建Python虚拟环境..."
        python3 -m venv "$VENV_DIR" || {
            print_error "无法创建虚拟环境"
            return 1
        }
        print_success "虚拟环境创建完成"
    fi
    
    # 激活虚拟环境
    source "$VENV_DIR/bin/activate" || {
        print_error "无法激活虚拟环境"
        return 1
    }
    
    # 升级pip
    print_info "升级pip到最新版本..."
    pip install --upgrade pip 2>&1 | tee -a "$LOG_FILE"
    
    # 安装Python依赖包
    print_info "安装Python项目依赖..."
    if [[ -f "$PROJECT_DIR/requirements.txt" ]]; then
        pip install -r "$PROJECT_DIR/requirements.txt" 2>&1 | tee -a "$LOG_FILE" || {
            print_error "Python依赖包安装失败"
            return 1
        }
        print_success "Python依赖包安装完成"
    else
        print_warning "未找到requirements.txt文件"
    fi
    
    # 安装项目本身（开发模式）
    print_info "以开发模式安装项目..."
    pip install -e "$PROJECT_DIR" 2>&1 | tee -a "$LOG_FILE" || {
        print_warning "项目安装失败，但可能不影响运行"
    }
}

#=============================================================================
# 系统配置函数
#=============================================================================

# 创建用户和设置权限
setup_user_permissions() {
    print_header "7. 配置用户权限"
    
    request_sudo
    
    # 检查用户是否已存在
    if id "$SERVICE_USER" &>/dev/null; then
        print_info "服务用户已存在: $SERVICE_USER"
    else
        print_info "创建服务用户: $SERVICE_USER"
        sudo useradd -r -s /bin/false "$SERVICE_USER" || {
            print_warning "用户创建失败，将使用当前用户运行服务"
            SERVICE_USER="$USER"
        }
    fi
    
    # 将用户添加到bluetooth组
    sudo usermod -a -G bluetooth "$USER" 2>/dev/null
    if [[ "$SERVICE_USER" != "$USER" ]]; then
        sudo usermod -a -G bluetooth "$SERVICE_USER" 2>/dev/null
    fi
    print_success "用户权限配置完成"
    
    # 创建必要的目录
    print_info "创建项目目录..."
    sudo mkdir -p "$CONFIG_DIR" "$DATA_DIR" "$LOG_DIR" 2>/dev/null
    
    # 复制配置文件
    if [[ -f "$PROJECT_DIR/config/ble_config.yaml" ]]; then
        sudo cp "$PROJECT_DIR/config/ble_config.yaml" "$CONFIG_DIR/" 2>/dev/null
        print_success "配置文件复制完成"
    fi
    
    # 设置目录权限
    sudo chown -R "$SERVICE_USER:bluetooth" "$DATA_DIR" 2>/dev/null
    sudo chmod -R 755 "$DATA_DIR" 2>/dev/null
}

# 配置polkit权限
setup_polkit_permissions() {
    print_header "8. 配置polkit权限"
    
    request_sudo
    
    if [[ -f "$PROJECT_DIR/polkit/50-cloud-printer-ble.rules" ]]; then
        print_info "复制polkit规则文件..."
        sudo cp "$PROJECT_DIR/polkit/50-cloud-printer-ble.rules" /etc/polkit-1/rules.d/ 2>/dev/null || {
            print_warning "polkit规则文件复制失败"
            return 1
        }
        
        # 重启polkit服务
        sudo systemctl restart polkit 2>/dev/null || print_warning "无法重启polkit服务"
        print_success "polkit权限配置完成"
    else
        print_warning "未找到polkit规则文件"
    fi
}

# 启动系统服务
start_system_services() {
    print_header "9. 启动系统服务"
    
    request_sudo
    
    # 启动蓝牙服务
    print_info "启动蓝牙服务..."
    sudo systemctl enable bluetooth 2>&1 | tee -a "$LOG_FILE"
    sudo systemctl start bluetooth 2>&1 | tee -a "$LOG_FILE"
    
    if systemctl is-active --quiet bluetooth; then
        print_success "蓝牙服务启动成功"
    else
        print_error "蓝牙服务启动失败"
        return 1
    fi
    
    # 检查NetworkManager
    if ! systemctl is-active --quiet NetworkManager && ! systemctl is-active --quiet network-manager; then
        print_info "启动NetworkManager..."
        sudo systemctl enable NetworkManager 2>&1 | tee -a "$LOG_FILE"
        sudo systemctl start NetworkManager 2>&1 | tee -a "$LOG_FILE"
    fi
}

#=============================================================================
# 服务启动函数
#=============================================================================

# 直接启动服务（前台模式）
start_service_direct() {
    print_header "启动BLE GATT服务（直接模式）"
    
    # 激活虚拟环境
    source "$VENV_DIR/bin/activate"
    
    # 设置环境变量
    export PYTHONPATH="$PROJECT_DIR"
    export BLE_CONFIG_PATH="$CONFIG_DIR/ble_config.yaml"
    
    print_info "启动参数:"
    print_info "  项目目录: $PROJECT_DIR"
    print_info "  配置文件: $BLE_CONFIG_PATH"
    print_info "  Python路径: $PYTHONPATH"
    
    # 检查入口文件
    if [[ -f "$PROJECT_DIR/src/ble/gatt_server.py" ]]; then
        print_info "启动BLE GATT服务器..."
        echo -e "${YELLOW}按Ctrl+C停止服务${NC}"
        echo ""
        
        cd "$PROJECT_DIR"
        python3 -m src.ble.gatt_server
        
    elif [[ -f "$PROJECT_DIR/src/network/service.py" ]]; then
        print_info "启动网络服务..."
        echo -e "${YELLOW}按Ctrl+C停止服务${NC}"
        echo ""
        
        cd "$PROJECT_DIR"
        python3 -m src.network.service --config "$BLE_CONFIG_PATH"
        
    else
        print_error "未找到服务入口文件"
        return 1
    fi
}

# 以systemd服务模式启动
start_service_systemd() {
    print_header "配置systemd服务"
    
    request_sudo
    
    # 检查服务文件
    if [[ -f "$PROJECT_DIR/systemd/cloud-printer-ble.service" ]]; then
        print_info "复制systemd服务文件..."
        sudo cp "$PROJECT_DIR/systemd/cloud-printer-ble.service" /etc/systemd/system/ 2>&1 | tee -a "$LOG_FILE"
        
        # 修改服务文件中的路径
        sudo sed -i "s|/opt/cloud-printer|$PROJECT_DIR|g" /etc/systemd/system/cloud-printer-ble.service
        sudo sed -i "s|/etc/cloud-printer/ble_config.yaml|$CONFIG_DIR/ble_config.yaml|g" /etc/systemd/system/cloud-printer-ble.service
        
        # 重载systemd配置
        print_info "重载systemd配置..."
        sudo systemctl daemon-reload 2>&1 | tee -a "$LOG_FILE"
        
        # 启用并启动服务
        print_info "启用并启动服务..."
        sudo systemctl enable cloud-printer-ble 2>&1 | tee -a "$LOG_FILE"
        sudo systemctl start cloud-printer-ble 2>&1 | tee -a "$LOG_FILE"
        
        # 检查服务状态
        sleep 2
        if systemctl is-active --quiet cloud-printer-ble; then
            print_success "服务启动成功"
            
            print_info "服务状态:"
            sudo systemctl status cloud-printer-ble --no-pager -l
            
            print_info "查看服务日志:"
            echo "  sudo journalctl -u cloud-printer-ble -f"
            
        else
            print_error "服务启动失败"
            print_info "查看错误日志:"
            sudo journalctl -u cloud-printer-ble --no-pager -l
            return 1
        fi
    else
        print_error "未找到systemd服务文件"
        return 1
    fi
}

# 运行测试验证
run_tests() {
    print_header "运行验证测试"
    
    # 激活虚拟环境
    source "$VENV_DIR/bin/activate"
    
    cd "$PROJECT_DIR"
    
    # 运行简单测试
    if [[ -f "simple_test.py" ]]; then
        print_info "运行简单验证测试..."
        python3 simple_test.py 2>&1 | tee -a "$LOG_FILE"
    fi
    
    # 运行单元测试（如果存在）
    if [[ -d "tests" ]] && command_exists pytest; then
        print_info "运行单元测试..."
        pytest tests/ -v --tb=short 2>&1 | tee -a "$LOG_FILE" || {
            print_warning "部分测试失败，但不影响服务运行"
        }
    fi
    
    # 检查蓝牙设备扫描
    if command_exists hcitool; then
        print_info "测试蓝牙扫描功能..."
        timeout 5 hcitool lescan 2>&1 | tee -a "$LOG_FILE" || {
            print_warning "蓝牙扫描测试失败"
        }
    fi
}

#=============================================================================
# 主要启动模式选择
#=============================================================================

# 显示启动选项菜单
show_startup_menu() {
    echo ""
    echo -e "${CYAN}请选择启动模式:${NC}"
    echo "  1) 直接启动 (前台运行，适合开发调试)"
    echo "  2) systemd服务 (后台运行，适合生产环境)" 
    echo "  3) 仅运行测试验证"
    echo "  4) 完整设置 (安装依赖 + 配置 + 启动服务)"
    echo "  5) 仅安装依赖和配置"
    echo "  q) 退出脚本"
    echo ""
}

# 处理用户选择
handle_user_choice() {
    local choice
    read -p "请输入选择 [1-5,q]: " choice
    
    case $choice in
        1)
            print_info "选择: 直接启动模式"
            start_service_direct
            ;;
        2)
            print_info "选择: systemd服务模式"
            start_service_systemd
            ;;
        3)
            print_info "选择: 仅运行测试"
            run_tests
            ;;
        4)
            print_info "选择: 完整设置"
            install_system_dependencies && \
            setup_python_environment && \
            setup_user_permissions && \
            setup_polkit_permissions && \
            start_system_services && \
            start_service_direct
            ;;
        5)
            print_info "选择: 仅安装和配置"
            install_system_dependencies && \
            setup_python_environment && \
            setup_user_permissions && \
            setup_polkit_permissions && \
            start_system_services
            print_success "安装和配置完成，可以手动启动服务"
            ;;
        q|Q)
            print_info "退出脚本"
            exit 0
            ;;
        *)
            print_error "无效选择，请重新选择"
            return 1
            ;;
    esac
}

#=============================================================================
# 清理和退出函数
#=============================================================================

# 信号处理函数
cleanup() {
    print_info "接收到退出信号，正在清理..."
    
    # 停止可能正在运行的进程
    pkill -f "python3 -m src.ble.gatt_server" 2>/dev/null
    pkill -f "python3 -m src.network.service" 2>/dev/null
    
    print_info "清理完成"
    exit 0
}

# 设置信号处理
trap cleanup SIGINT SIGTERM

#=============================================================================
# 主程序入口
#=============================================================================

main() {
    # 显示脚本头部
    show_header
    
    # 检查基本环境
    check_os || exit 1
    check_python || {
        print_error "Python环境检查失败，请先安装Python3.8+"
        exit 1
    }
    
    check_system_services
    check_bluetooth_hardware
    
    # 显示当前状态摘要
    echo ""
    print_info "环境检查完成，当前状态:"
    print_info "  项目目录: $PROJECT_DIR"
    print_info "  虚拟环境: $VENV_DIR"
    print_info "  配置目录: $CONFIG_DIR"
    print_info "  日志文件: $LOG_FILE"
    
    # 如果有命令行参数，直接执行对应操作
    if [[ $# -gt 0 ]]; then
        case $1 in
            --direct|-d)
                print_info "命令行模式: 直接启动"
                start_service_direct
                ;;
            --systemd|-s)
                print_info "命令行模式: systemd服务"
                start_service_systemd
                ;;
            --test|-t)
                print_info "命令行模式: 运行测试"
                run_tests
                ;;
            --install|-i)
                print_info "命令行模式: 安装依赖"
                install_system_dependencies && \
                setup_python_environment && \
                setup_user_permissions && \
                setup_polkit_permissions && \
                start_system_services
                ;;
            --full|-f)
                print_info "命令行模式: 完整设置"
                install_system_dependencies && \
                setup_python_environment && \
                setup_user_permissions && \
                setup_polkit_permissions && \
                start_system_services && \
                start_service_direct
                ;;
            --help|-h)
                echo "用法: $0 [选项]"
                echo "选项:"
                echo "  -d, --direct   直接启动服务"
                echo "  -s, --systemd  以systemd服务启动"
                echo "  -t, --test     运行测试验证"
                echo "  -i, --install  仅安装依赖和配置"
                echo "  -f, --full     完整设置并启动"
                echo "  -h, --help     显示帮助信息"
                exit 0
                ;;
            *)
                print_error "未知参数: $1"
                print_info "使用 $0 --help 查看帮助"
                exit 1
                ;;
        esac
    else
        # 交互式模式
        while true; do
            show_startup_menu
            if handle_user_choice; then
                break
            fi
        done
    fi
    
    print_success "脚本执行完成"
    print_info "日志文件: $LOG_FILE"
}

#=============================================================================
# 脚本执行入口
#=============================================================================

# 检查脚本是否被直接执行
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
    main "$@"
fi

# 脚本结束